package com.youge.listener;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * @author: hcf
 * @qq: 46914685
 * @email: 46914685@qq.com
 * @date: 2020-10-11 20:28
 */

/**
 * Consumer ACK机制:
 * 1.设置手动签收.acknowledge="manual"
 * 2.让监听器类实现 ChannelAwareMessageListener 接口
 * 3.如果消息成功处理,则调用 channel的basicAck()签收
 * 4.如果消息处理失败,则调用channel的basicNack()拒绝签收,broker重新发送给consumer
 */
@Component
public class AckListener implements ChannelAwareMessageListener {

    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        Thread.sleep(1000);

        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            //1.接收转换消息
            System.out.println(new String(message.getBody()));
            //2.处理业务逻辑
            System.out.println("处理业务逻辑....");

//            模拟出现错误
//            int i = 10 / 0;

            //3.手动签收
            /**
             * basicAck(long deliveryTag, boolean multiple)
             * multiple 是否处理多条
             */
            channel.basicAck(deliveryTag, true);
        } catch (Exception e) {
//            e.printStackTrace();
//            4.拒绝签收
            /**
             * basicNack(long deliveryTag, boolean multiple, boolean requeue)
             * requeue:重回队列.如果设置为true,则消息重新回到queue,broker会重新发送
             *         该消息给消费端
             */
            System.out.println("出现错误,拒绝签收....");
            channel.basicNack(deliveryTag, true, true);
        }

    }
}
